#!/usr/bin/python
# LED "daemon"
#
# Copyright (C) 2013 Anselm Lingnau <anselm@anselms.net>
#
# This daemon listens on port localhost:33333. Clients can send a
# string containing the letters "rgbycmwxq". Every letter stands for
# a colour. The LED will flash this colour for STEP seconds before
# going on to the next colour. When the string has been exhausted,
# it restarts from the beginning unless another string has been
# submitted in the meantime. There is no queueing; whichever string
# was submitted most recently when the current string is finished
# will be used next.
# The letter "q" is similar to "x" (LED off) but also sets the
# string to "x" so the LED will stay off until another string is
# submitted.

import threading
import SocketServer
import led

STEP = 0.2

class LockedData():
    def __init__(self):
        self.data = ''
        self.lock = threading.Lock()
    def get(self):
        with self.lock:
            data = self.data
        return data
    def set(self, data):
        with self.lock:
            self.data = data

led_data = LockedData()
led_data.set("rrrrrxxxxx")

class LedHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024).strip()
        led_data.set(data)
        print "Set LED data to '%s'" % data
        self.request.sendall("OK\n")

class LedServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description='Control LED output')
    parser.add_argument('--host', dest='host', default='localhost',
                        help='Host name/IP address to listen on')
    parser.add_argument('--port', dest='port', type=int,
                        default=33333, help='Port to listen on')
    parser.add_argument('--step', dest='step', type=float,
                        default=STEP, help='Step size for blinking')
    parser.add_argument('sequence', metavar='SEQUENCE', nargs='*',
                        help='Initial sequence to be displayed')
    args = parser.parse_args()

    server = LedServer((args.host, args.port), LedHandler)
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()

    if args.sequence:
        led_data.set("".join(args.sequence))

    while True:
        this_data = led_data.get()
        for c in this_data:
            if c == 'q':
                c = 'x'
                led_data.set(c)
            led.blink(c, step=args.step)
